package com.bsg.upm.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.bsg.upm.check.CheckResult;
import com.bsg.upm.check.UserRoleCheck;
import com.bsg.upm.constant.DictTypeConstants;
import com.bsg.upm.constant.OperateDictConstants;
import com.bsg.upm.constant.OperateDictTypeConstants;
import com.bsg.upm.dto.UserDto;
import com.bsg.upm.dto.UserRoleDto;
import com.bsg.upm.entity.UserEntity;
import com.bsg.upm.entity.UserRoleEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;

/**
 * 角色管理业务处理类
 * 
 * @author HCK
 *
 */
@Service
public class UserRoleService extends BaseService {

	@Resource
	private UserService userService;

	@Resource
	private UserRoleCheck userRoleCheck;

	/**
	 * 用户角色查询
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson list(Map<String, Object> paramMap) throws APIException {
		try {
			JSONArray results = new JSONArray();

			// 获取指定条件的角色
			List<UserRoleEntity> roles = userRoleDao.list(paramMap);

			for (UserRoleEntity role : roles) {
				// 构建角色展示对象
				UserRoleDto roleDto = buildShowDto(role, false);
				results.add(roleDto);
			}

			return RespJsonFactory.buildOK(results);
		} catch (Exception e) {
			logger.error("用户角色查询异常", e);
			throw new APIException("用户角色查询异常:" + e.getMessage());
		}
	}

	/**
	 * 用户角色详情
	 * 
	 * @param roleCode
	 *            角色编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson get(String roleCode) throws APIException {
		try {
			// 获取指定的用户角色
			UserRoleEntity role = userRoleDao.get(roleCode);
			if (role == null) {
				return RespJsonFactory.build(HttpStatus.SC_GONE, "该角色不存在");
			}

			// 构建角色展示对象
			UserRoleDto roleDto = buildShowDto(role, true);

			return RespJsonFactory.buildOK(roleDto);
		} catch (Exception e) {
			logger.error("用户角色获取异常", e);
			throw new APIException("用户角色获取异常:" + e.getMessage());
		}
	}

	/**
	 * 用户角色新增
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson save(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_ADD;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 用户角色新增检查
			CheckResult chkRS = userRoleCheck.checkSave(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建角色对象
			UserRoleEntity role = buildUserRole(paramMap);
			userRoleDao.save(role);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_USER_ROLE, operateAcion, role.getCode(), role.getName());

			return RespJsonFactory.buildCreated();
		} catch (Exception e) {
			logger.error("用户角色" + operateAcionText + "异常", e);
			throw new APIException("用户角色" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 用户角色编辑
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson update(Map<String, Object> paramMap) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_UPDATE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 用户角色编辑检查
			CheckResult chkRS = userRoleCheck.checkUpdate(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			// 构建角色对象
			UserRoleEntity role = buildUserRoleToUpdate(paramMap);
			userRoleDao.update(role);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_USER_ROLE, operateAcion, role.getCode(), role.getName());

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			logger.error("用户角色" + operateAcionText + "异常", e);
			throw new APIException("用户角色" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 用户角色删除
	 * 
	 * @param roleCode
	 *            角色编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	@Transactional(rollbackFor = APIException.class)
	public RespJson remove(String roleCode) throws APIException {
		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_REMOVE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定的用户角色
			UserRoleEntity role = userRoleDao.get(roleCode);

			// 用户角色删除检查
			CheckResult chkRS = userRoleCheck.checkRemove(role);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			userRoleDao.remove(roleCode);

			// 保存操作日志
			saveOperateLog(OperateDictConstants.MODEL_USER_ROLE, operateAcion, role.getCode(), role.getName());

			return RespJsonFactory.buildNoContent();
		} catch (Exception e) {
			logger.error("用户角色" + operateAcionText + "异常", e);
			throw new APIException("用户角色" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 构建角色展示对象
	 * 
	 * @param role
	 *            角色对象
	 * @param showDetail
	 *            是否展示详情
	 * @return 角色展示对象
	 */
	private UserRoleDto buildShowDto(UserRoleEntity role, boolean showDetail) {
		UserRoleDto roleDto = buildRoleBaseDto(role);
		List<UserEntity> users = role.getUsers();
		List<UserDto> userDtos = new ArrayList<>(users.size());
		roleDto.setUsers(userDtos);

		for (UserEntity user : users) {
			UserDto userDto = userService.buildUserBaseDto(user);
			userDtos.add(userDto);
		}
		return roleDto;
	}

	/**
	 * 构建角色基础展示对象
	 * 
	 * @param role
	 *            角色对象
	 * @return 角色基础展示对象
	 */
	public UserRoleDto buildRoleBaseDto(UserRoleEntity role) {
		UserRoleDto roleDto = new UserRoleDto();
		roleDto.setCode(role.getCode());
		roleDto.setName(role.getName());
		roleDto.setLevel(role.getLevel());
		roleDto.setDataScope(role.getDataScope());
		roleDto.setDataScopeText(dictTypeCache.getTextFromCache(DictTypeConstants.DATA_SCOPE, role.getDataScope()));
		roleDto.setDescription(role.getDescription());
		return roleDto;
	}

	/**
	 * 构建角色对象
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 角色对象
	 */
	private UserRoleEntity buildUserRole(Map<String, Object> paramMap) {
		UserRoleEntity role = new UserRoleEntity();
		role.setCode(StringUtils.trim((String) paramMap.get("code")));
		role.setName(StringUtils.trim((String) paramMap.get("name")));
		role.setLevel((Integer) paramMap.get("level"));
		role.setDataScope(StringUtils.trim((String) paramMap.get("dataScope")));
		role.setDescription(StringUtils.trim((String) paramMap.get("description")));
		return role;
	}

	/**
	 * 构建角色对象用于更新操作
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return 角色对象
	 */
	private UserRoleEntity buildUserRoleToUpdate(Map<String, Object> paramMap) {
		UserRoleEntity role = userRoleDao.get((String) paramMap.get("code"));
		if (paramMap.containsKey("name")) {
			role.setName(StringUtils.trim((String) paramMap.get("name")));
		}

		if (paramMap.containsKey("level")) {
			role.setLevel((Integer) paramMap.get("level"));
		}

		if (paramMap.containsKey("dataScope")) {
			role.setDataScope(StringUtils.trim((String) paramMap.get("dataScope")));
		}

		if (paramMap.containsKey("description")) {
			role.setDescription(StringUtils.trim((String) paramMap.get("description")));
		}
		return role;
	}

}
